﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using PlayerIO.GameLibrary;
using System.Drawing;

namespace UnchartedSkies
{
	//Player class. each player that join the game will have these attributes.
	public class Player : BasePlayer {
        public String username;
        public DateTime joinedTime;
        public Boolean isSelected = false;
	}

    /**
     *  Liste d'attente pour rejoindre une game
     * 
     * 
     * */
   
	[RoomType("MatchMaking")]
	public class GameCode : Game<Player> {
        private const String MATCH_MAKING_FFA = "$MatchMaking-FFA$";
        private const String MATCH_MAKING_CTF = "$MatchMaking-CTF$";
        private const String MATCH_MAKING_1ON1_LADDER = "$MatchMaking-1ON1-Ladder$";

        //PROTOCOLE
        private const string PROTOCOLE_STARTING_GAME = "psg";

        private BasicMatchMaking m;

		// This method is called when an instance of your the game is created
		public override void GameStarted() {
			// anything you write to the Console will show up in the 
			// output window of the development server
			Console.WriteLine("Service room started");
            Console.Write("Room id : " + this.RoomId);

            if (this.RoomId.Equals(MATCH_MAKING_FFA))
            {
                Console.WriteLine("Match Making FFA service room started");
                m = new MatchMakingFFA();
                m.initialize();
            }
            if (this.RoomId.Equals(MATCH_MAKING_CTF))
            {
                m = new MatchMakingCTF();
                m.initialize();
            }

		}

		// This method is called when the last player leaves the room, and it's closed down.
		public override void GameClosed() {
			Console.WriteLine("RoomId: " + RoomId);
		}

		// This method is called whenever a player joins the game
		public override void UserJoined(Player player) {
			
             player.username = player.JoinData["username"];
             player.joinedTime = DateTime.Now;
             Console.WriteLine("User joined : " + player.username+", playerCount : "+this.PlayerCount);

             int numberPlayersDispo = 0;
             foreach (var p in this.Players)
             {
                 if (!p.isSelected)
                     numberPlayersDispo++;
             }
             
             if (m.numberPlayersNeeded <= numberPlayersDispo)
             {
                 Console.WriteLine("Number of players reached !");
                 sendGameStartToPlayers();
             }

			

		}

		// This method is called when a player leaves the game
		public override void UserLeft(Player player) {
			//Tell the chat that the player left.
			//Broadcast("ChatLeft", player.Id);
		}

		// This method is called when a player sends a message into the server code
		public override void GotMessage(Player player, Message message) {
			switch(message.Type) {
				case "start": {
						Broadcast("start", player.Id, player.ConnectUserId, message.GetInt(0), message.GetInt(1));
						break;
					}
				case "stop": {
						Broadcast("stop", player.Id);
						break;
					}
				case "move": {
						Broadcast("move", player.Id, message.GetInt(0), message.GetInt(1));
						break;
					}
				case "ChatMessage":{
						Broadcast("ChatMessage", player.Id, message.GetString(0));
						break;
					}
			}
		}


        private void sendGameStartToPlayers()
        {

            List<Player> selectedList = new List<Player>();

            //Sélectionne les m.playerRequis
            for (int i = 0; i < m.numberPlayersNeeded; i++)
            {
                Player selectedPlayer = null;
                foreach (var p in this.Players)
                {
                    if (selectedPlayer == null) 
                    {
                        if(!selectedList.Contains(p) && !p.isSelected)
                            selectedPlayer = p; 

                    } else{
                        if (p.joinedTime < selectedPlayer.joinedTime && !selectedList.Contains(p) && !p.isSelected)
                            selectedPlayer = p;
                    }
                }
                Console.WriteLine("Adding player : " + selectedPlayer.username);
                selectedPlayer.isSelected = true;
                selectedList.Add(selectedPlayer);
            }

            Console.WriteLine("Sending game starting & infos to those players");

            //Construit le message à envoyé avec la liste des joueurs
            Message msg = Message.Create(PROTOCOLE_STARTING_GAME);
            msg.Add(m.generateRoomId());
            msg.Add(m.getRoomType());
            msg.Add(m.getMap());
            msg.Add(selectedList.Count);
   
            //Récupère les infos des joueurs
            foreach (var ps in selectedList)
            {
                msg.Add(ps.username);
                msg.Add(ps.ConnectUserId);
            }
            //Envoi à tous les joueurs
            foreach (var ps in selectedList)
            {
                ps.Send(msg);
                ps.Disconnect();
            }

        }



	}
}